package com.wxzz.elearing.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.wxzz.elearing.user.dto.AdminRoleDto;
import com.wxzz.elearing.user.dto.AdminRolePermissionDto;
import com.wxzz.elearing.user.entity.*;
import com.wxzz.elearing.user.mapper.*;
import com.wxzz.elearing.user.service.IAdminPermissionDisabledService;
import com.wxzz.elearing.user.service.IAdminPermissionService;
import com.wxzz.elearing.user.service.IAdminRoleService;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.ExcelUtils;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author
 * @since 2021-03-11
 */
@Service
public class AdminRoleServiceImpl extends ServiceImpl<AdminRoleMapper, AdminRole> implements IAdminRoleService {

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Override
    public ReturnVO saveAdminRole(AdminRole adminRole) {
        adminRoleMapper.insert(adminRole);
        return new ReturnVO("角色添加成功", adminRole.getId());
    }

    @Override
    public ReturnVO updateAdminRole(AdminRole adminRole) {
        adminRoleMapper.updateById(adminRole);
        return new ReturnVO("角色名修改成功", adminRole.getId());
    }

    @Override
    public ReturnVO deleteAdminRole(Long adminRoleId) {
        AdminRole adminRole = adminRoleMapper.selectById(adminRoleId);
        Optional.ofNullable(adminRole).orElseThrow(() -> new ServiceException("该角色已不存在"));
        if (adminRole.getRoleType() != null && (adminRole.getRoleType() == 1 || adminRole.getRoleType() == 2)) {
            throw new ServiceException("特殊角色无法进行修改");
        }
        adminRoleMapper.deleteById(adminRoleId);
        return new ReturnVO("角色删除成功", adminRoleId);
    }

    @SneakyThrows
    @Override
    public ReturnVO<JgPageVo<List<AdminRole>>> listAdminRole(HttpServletResponse response, Long enterpriseId, AdminRoleDto adminRoleDto) {
        PageHelper.startPage(adminRoleDto.getCurPage(), adminRoleDto.getMaxPage());
        QueryWrapper<AdminRole> queryWrapper = new QueryWrapper();
        queryWrapper.eq("enterprise_id", enterpriseId);
        queryWrapper.orderByDesc("create_time");
        if (StringUtils.isNotBlank(adminRoleDto.getRoleName())) {
            queryWrapper.like("role_name", adminRoleDto.getRoleName() + "%");
        }
        if (StringUtils.isNotBlank(adminRoleDto.getRemark())) {
            queryWrapper.eq("remark", adminRoleDto.getRemark());
        }
        List<AdminRole> list = adminRoleMapper.selectList(queryWrapper);
        if (adminRoleDto.getIsExport() != null && adminRoleDto.getIsExport() == 1) {
            ExcelUtils.exportExcel(list, "角色列表", "角色信息", AdminRole.class, "角色信息", response);
        }
        return new ReturnVO<>("角色列表查询成功", new JgPageVo(new PageInfo<>(list)));
    }

    @Autowired
    private AdminUserRoleMapper adminUserRoleMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private IAdminPermissionService adminPermissionService;

    @Autowired
    private AdminPermissionDisabledMapper adminPermissionDisabledMapper;

    @Override
    public ReturnVO updateAdminUserRole(Long enterpriseId, AdminUserRole adminUserRole) {
        if (adminUserRole.getAdminUserId() == null) {
            throw new ServiceException("请传入用户id");
        }
        adminUserRoleMapper.deleteAdminUserRoleByAdminUserId(adminUserRole.getAdminUserId());
        adminUserRoleMapper.insert(adminUserRole);
        //修改角色权限时 缓存信息无法实时更新 暂时注释
//        //更新缓存中用户对应的权限信息
//        if (adminUserRole.getAdminRoleId() != null) {
//            List<AdminPermission> permissions = adminUserRoleMapper.selectAllPermissionByRoleId(adminUserRole.getAdminRoleId());
//            //查询被禁用的权限
//            List<Long> disabledIds = adminPermissionDisabledMapper.selectAdminPermissionDisabledByEnterpriseId(enterpriseId);
//            adminPermissionService.removePermissions(permissions,disabledIds);
//            List<String> uri = Lists.newArrayList();
//            for (AdminPermission permission : permissions) {
//                uri.add(permission.getUri());
//            }
//            redisTemplate.opsForValue().set(RedisConstants.USER_PERMISSION + adminUserRole.getAdminUserId(), JSONObject.toJSONString(uri));
//        }
        return new ReturnVO<>("用户角色分配成功", adminUserRole.getId());
    }

    @Autowired
    private AdminRolePermissionMapper adminRolePermissionMapper;

    @Override
    public ReturnVO updateAdminRolePermission(AdminRolePermissionDto adminRolePermissionDto) {
        if (adminRolePermissionDto.getAdminRoleId() == null) {
            throw new ServiceException("请传入adminRoleId");
        }
        AdminRole adminRole = adminRoleMapper.selectById(adminRolePermissionDto.getAdminRoleId());
        Optional.ofNullable(adminRole).orElseThrow(() -> new ServiceException("该角色已不存在"));
        if (adminRole.getRoleType() != null && (adminRole.getRoleType() == 1 || adminRole.getRoleType() == 2)) {
            throw new ServiceException("特殊角色无法进行修改");
        }
        if (adminRolePermissionDto.getAdminRoleId() == 1) {
            throw new ServiceException("管理员角色无法修改");
        }
        adminRolePermissionMapper.deleteAdminRolePermissionByAdminRoleId(adminRolePermissionDto.getAdminRoleId());
        if (adminRolePermissionDto.getAdminPermissionIds() != null) {
            for (Long adminPermissionId : adminRolePermissionDto.getAdminPermissionIds()) {
                AdminRolePermission adminRolePermission = new AdminRolePermission();
                adminRolePermission.setAdminRoleId(adminRolePermissionDto.getAdminRoleId());
                adminRolePermission.setAdminPermissionId(adminPermissionId);
                adminRolePermissionMapper.insert(adminRolePermission);
            }
        }
        //删除这个企业的权限缓存
        Set<String> keys = redisTemplate.keys(RedisConstants.PERMISSION + adminRole.getEnterpriseId() + "*");
        if (keys != null) {
            redisTemplate.delete(keys);
        }
        return new ReturnVO<>("角色权限分配成功", null);
    }

    @Autowired
    private AdminPermissionMapper adminPermissionMapper;

    /**
     * 添加讲师角色
     *
     * @param adminUserId
     * @param enterpriseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTeacherRole(Long adminUserId, Long enterpriseId) {
        //查询是否拥有该特殊角色
        List<AdminRole> adminRoles = adminRoleMapper.selectList(new LambdaQueryWrapper<AdminRole>()
                .eq(AdminRole::getEnterpriseId, enterpriseId)
                .eq(AdminRole::getRoleType, 2));
        Long adminRoleId = 0L;
        if (adminRoles.size() == 0) {
            //没有则创建角色
            AdminRole adminRole = new AdminRole();
            if (enterpriseId == 0) {
                adminRole.setRemark("平台讲师角色");
                adminRole.setRoleName("平台讲师");
            }
            if (enterpriseId != 0) {
                adminRole.setRemark("企业讲师角色");
                adminRole.setRoleName("企业讲师");
            }
            adminRole.setEnterpriseId(enterpriseId);
            adminRole.setRoleType(2);
            adminRoleMapper.insert(adminRole);
            adminRoleId = adminRole.getId();
        } else {
            adminRoleId = adminRoles.get(0).getId();
        }
        //删除用户原来的角色权限
        adminRolePermissionMapper.delete(new LambdaQueryWrapper<AdminRolePermission>()
                .eq(AdminRolePermission::getAdminRoleId, adminRoleId));
        //角色关联用户
        AdminUserRole adminUserRole = new AdminUserRole();
        adminUserRole.setAdminUserId(adminUserId);
        adminUserRole.setAdminRoleId(adminRoleId);
        adminUserRoleMapper.insert(adminUserRole);
        List<AdminPermission> permissions = null;
        //查询所有权限
        if (enterpriseId == 0) {
            permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
                    .eq(AdminPermission::getPermissionType, 2));
        }
        if (enterpriseId != 0) {
            permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
                    .eq(AdminPermission::getPermissionType, 3));
        }
        for (AdminPermission permission : permissions) {
            //给角色分配权限
            AdminRolePermission adminRolePermission = new AdminRolePermission();
            adminRolePermission.setAdminRoleId(adminRoleId);
            adminRolePermission.setAdminPermissionId(permission.getId());
            adminRolePermissionMapper.insert(adminRolePermission);
        }
        //删除这权限缓存
        Set<String> keys = redisTemplate.keys(RedisConstants.PERMISSION + enterpriseId + ":" + adminUserId);
        if (keys != null) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 添加试讲讲师角色
     *
     * @param adminUserId
     * @param enterpriseId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTrialTeacherRole(Long adminUserId, Long enterpriseId) {
        //创建角色
        AdminRole adminRole = new AdminRole();
        if (enterpriseId == 0) {
            throw new ServiceException("平台无法添加试讲讲师");
        }
        adminRole.setRemark("试讲讲师讲师角色");
        adminRole.setRoleName("试讲讲师");
        adminRole.setEnterpriseId(enterpriseId);
        adminRole.setRoleType(2);
        adminRoleMapper.insert(adminRole);
        //删除用户原来的角色权限
        adminRolePermissionMapper.delete(new LambdaQueryWrapper<AdminRolePermission>()
                .eq(AdminRolePermission::getAdminRoleId, adminRole.getId()));
        //角色关联用户
        AdminUserRole adminUserRole = new AdminUserRole();
        adminUserRole.setAdminUserId(adminUserId);
        adminUserRole.setAdminRoleId(adminRole.getId());
        adminUserRoleMapper.insert(adminUserRole);
        //查询所有试讲讲师权限
        List<AdminPermission> permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
                .eq(AdminPermission::getPermissionType, 4));
        for (AdminPermission permission : permissions) {
            //给角色分配权限
            AdminRolePermission adminRolePermission = new AdminRolePermission();
            adminRolePermission.setAdminRoleId(adminRole.getId());
            adminRolePermission.setAdminPermissionId(permission.getId());
            adminRolePermissionMapper.insert(adminRolePermission);
        }
        //删除这权限缓存
        Set<String> keys = redisTemplate.keys(RedisConstants.PERMISSION + enterpriseId + ":" + adminUserId);
        if (keys != null) {
            redisTemplate.delete(keys);
        }
    }

}
